﻿using CoreRp.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;

namespace CoreRp.Services.Rap
{
   
    public static class S_Menu
    {
        //private static LazyCache.CachingService lazyserv = new LazyCache.CachingService();
        static List<Models.M_MenuInfo> Store_MainMenus;
        public static List<Models.M_MenuInfo> GetMenus(IUrlHelper url)
        {
            //var key = string.Join("|", Roles.Select(x => x.ToString()));
            //var oldMenu = lazyserv.Get<List<Models.M_MenuInfo>>(key);
            //if (oldMenu!=null)
            //{
            //    return oldMenu;
            //}
            if (Store_MainMenus != null)
            {
                return Store_MainMenus;
            }
            List<Models.M_MenuInfo> menus = new List<Models.M_MenuInfo>();

            var asbly = Assembly.GetExecutingAssembly();
            var types = asbly.GetTypes();
            Dictionary<string, M_MenuInfo> dicNamespaceMenuInfo = new Dictionary<string, M_MenuInfo>();
            List<M_MenuInfo> LeafMenus = new List<M_MenuInfo>();
            foreach (var type in types)
            {
                if (type.Namespace!=null && type.Namespace.StartsWith("CoreRp.Pages."))
                {
                    if (type.GetInterface("IMenuConfig")!=null)
                    {// 展开菜单
                        if (!dicNamespaceMenuInfo.ContainsKey(type.Namespace))
                        {
                            var mc = (IMenuConfig)asbly.CreateInstance(type.FullName);
                            dicNamespaceMenuInfo.Add(type.Namespace, new M_MenuInfo()
                            {
                                MENUID=type.FullName,
                                MENUNAME=mc.MenuName,
                                NAMESPACE=type.Namespace,
                                Children=new List<M_MenuInfo>(),
                                MENUURL="",
                                OUTLINK=false
                            });
                        }
                    }
                    else
                    {
                        var ismenu = (Is_Menu)type.GetCustomAttributes(typeof(Is_Menu),false).FirstOrDefault();
                        if (ismenu != null)
                        {
                            LeafMenus.Add(new M_MenuInfo()
                            {
                                OUTLINK=false,
                                MENUURL= GetUrlFromNameSpace(type.FullName,url),
                                Children=null,
                                MENUID=type.FullName,
                                MENUNAME=ismenu.MenuName,
                                ROLES=ismenu.RoleCodes,
                                NAMESPACE=type.Namespace
                            });
                        }
                    }
                }
            }
            foreach(var m in LeafMenus)
            {
                if (dicNamespaceMenuInfo.TryGetValue(m.NAMESPACE,out M_MenuInfo mi))
                {
                    mi.Children.Add(m);
                }
                else
                {
                    AttachToParentMenu(dicNamespaceMenuInfo, m.NAMESPACE.Split(".").ToList(), m);
                }
            }
            List<M_MenuInfo> MainMenus = new List<M_MenuInfo>();
            foreach (var key in dicNamespaceMenuInfo.Keys)
            {
                var ns = key.Split(".").AsEnumerable();
                while (true)
                {
                    ns = ns.Take(ns.Count() - 1);
                    if (ns.Count() == 0)
                    {
                        break;
                    }
                    if (dicNamespaceMenuInfo.TryGetValue(String.Join(".",ns),out M_MenuInfo m)){
                        m.Children.Add(dicNamespaceMenuInfo[key]);
                        break;
                    }
                }
                if (ns.Count() == 0)
                {
                    MainMenus.Add(dicNamespaceMenuInfo[key]);
                }
            }
            for(var i = 0; i < MainMenus.Count; i++)
            {
                var m = MainMenus[i];
                if(m.Children==null || m.Children.Count == 0)
                {
                    MainMenus.RemoveAt(i);
                }
            }
            Store_MainMenus = MainMenus;
            return MainMenus;
        }
        public static string GetUrlFromNameSpace(string tname,IUrlHelper url)
        {
            var prefix = "CoreRp.Pages.";
            var appendfix = "Model";
            var alllen = tname.Length;
            tname = tname.Substring(prefix.Length,tname.Length-prefix.Length-appendfix.Length);
            return url.Content("~/" + tname.Replace(".", "/"));
        } 
        public static void AttachToParentMenu(Dictionary<string, M_MenuInfo> dicNamespaceMenuInfo ,IEnumerable<string> nspace,M_MenuInfo menu)
        {
            if (dicNamespaceMenuInfo.TryGetValue(string.Join(".",nspace), out M_MenuInfo mi))
            {
                mi.Children.Add(menu);
            }
            else
            {
                if (nspace.Count() > 0)
                {
                    AttachToParentMenu(dicNamespaceMenuInfo, nspace.Take(nspace.Count() - 1), menu);
                }
            }

        }

        public class M_MenuConfig
        {
            public Menu[] Menus { get; set; }
            public Menuconfig MenuConfig { get; set; }
        }

        public class Menuconfig
        {
            public bool Order { get; set; }
        }

        public class Menu
        {
            public string MenuCode { get; set; }
            public string MenuName { get; set; }
            public string[] Role { get; set; }
            public int OrderId { get; set; }
            public object[] Children { get; set; }
        }

    }
}
